function confirmClose() {
	window.parent.comet.xhr.open('GET', '/bridge/disconnect/?sessionID='+window.parent.top.name, false);
	window.parent.comet.xhr.send(null);
	var dummy = window.parent.comet.xhr.responseText;
	window.parent.close();
}

function listenCallback() {
	console.log('&&& xhr.readyState: ' + window.parent.comet.xhr.readyState + ' &&&'); 
	if (window.parent.comet.xhr.readyState !== 4) { 
		setTimeout(listen, 500); 
		return; 
	}
	window.parent.comet.responseText = window.parent.comet.xhr.responseText;
	console.log('### received onreadystatechange callback => sessionID: (' + window.parent.comet.sessionID + '), responseText: (' + window.parent.comet.responseText + ') ###');
	if (window.parent.comet.responseText && window.parent.comet.responseText!='') { 
		window.parent.comet.serviceBridgeManager.callback(JSON.parse(window.parent.comet.responseText)); 
	};
	listen();
}

function listen() {
	if (!window.parent.top.name) {
		window.parent.comet.sessionID = 'E8AF8357A8774BB98A96DF91AD12E7FF';
		window.parent.top.name = window.parent.comet.sessionID;
		console.log('XXX sessionID: (' + window.parent.comet.sessionID + ')');
	} else {
		window.parent.comet.sessionID = window.parent.top.name;
		console.log('YYY found previous sessionID (!= null), so reconnecting ... (' + window.parent.top.name + ') YYY');
	}
	window.parent.comet.xhr.onreadystatechange = listenCallback;
	window.parent.comet.xhr.open('GET', '/bridge/listen/?sessionID='+window.parent.top.name, true);
	window.parent.comet.xhr.send(null);
}

function ServiceBridgeManager() {
	console.log('*** Creating PalmServiceBridgeManager ***');
	this.requests = {};
}

window.parent.comet.serviceBridgeManager = new ServiceBridgeManager();
window.parent.comet.serviceBridgeManager.callback = function(response) {
	var timeout;
	console.log('PalmServiceBridgeManager received callback - response: ', response);
	var tokens = (function(r){ 
		var l=[]; 
		for (var t in r) { 
			if (t!=='limit'&&t!=='backoff') 
			l.push(t); 
		} 
		return l.sort(); 
	})(response);

	console.log('# of tokens in onreadystatechange callback response: ' + tokens.length + '', tokens);
	for (var i=0, token; token=tokens[i]; i++) {
		for (var j=0, payload; payload=response[token][j]; j++) {
			var req = window.parent.comet.serviceBridgeManager.requests[token];
			console.error('token: (', token, '), payload: (', payload, ')');
			if (!(token in window.parent.comet.serviceBridgeManager.requests)) {
				console.warn('WARNING !!! : (' + token + ') not in requests callback array! Will try to defer ...'); 
				var resp = {}; 
				resp[token]=[]; 
				resp[token].push(payload); 
				if ('limit' in response) resp['limit']=response['limit']-1; else resp['limit']=5; 
				if ('backoff' in response) resp['backoff']=response['backoff']*2; 
				else 
					resp['backoff']=500;

				timeout = setTimeout((function(resp){
					return function() { 
						if (!resp.limit) 
							return; 
						window.parent.comet.serviceBridgeManager.callback.call(null, resp); 
					}
				})(resp), resp.backoff);
				return;
			};
			if (req) {
				console.warn('Got it !!! dispatching (' + token + ') to:', req);
				try { req.onservicecallback(payload); }catch (err) { console.error('Exception in service callback: ', err); }
			};
		};
	};
};
				
window.parent.onbeforeunload = confirmClose;
listen();
window.parent.document.getElementById('mojo_app').src='index.html';
window.parent.document.getElementById('mojo_app').focus();
